<!--
 * @Author: boyyang
 * @Date: 2022-01-28 15:32:49
 * @LastEditTime: 2022-02-11 21:01:10
 * @LastEditors: boyyang
 * @Description: 
 * @FilePath: \boyyang\plugin\boyyangUI\switch\index.vue
-->

<template>
    <div
        :class="['y-switch']"
        @click="switchChange"
        @mouseenter="switchMouseEnter"
        @mousedown="switchMouseDown"
        @mouseleave="switchMouseLeave"
        @mouseup="switchMouseUp"
    >
        <div
            :class="['y-switch-btn', { 'y-switch-btn-active': props.status }, { 'y-switch-btn-disable': props.isDisable }]"
        >
            <div
                :class="['point', { 'point-after': props.status }, { 'point-change': isChangePoint }]"
            ></div>
            <div
                :class="['text-wrapper', { 'text-wrapper-before': props.status }, { 'text-wrapper-after': !props.status }]"
            >
                <span v-show="props.status">{{ props.trueLabel }}</span>
                <span v-show="!props.status">{{ props.falseLabel }}</span>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, reactive } from 'vue'
interface ISwitchProps {
    status: boolean;
    width?: number;
    trueLabel?: string | number;
    falseLabel?: string | number;
    trueLabelColor?: string;
    falseLabelColor?: string;
    isDisable?: boolean;
}

interface ISwitchEmits {
    (e: 'update:status', status: boolean): void
}

const props = withDefaults(defineProps<ISwitchProps>(), {
    width: 55,
    trueLabel: '',
    falseLabel: '',
    trueLabelColor: 'whitesmoke',
    falseLabelColor: 'black',
    isDisable: false
})

const emits = defineEmits<ISwitchEmits>()

const isChangePoint = ref<boolean>(false)

const switchChange = () => {
    if (props.isDisable) {
        return
    }
    emits('update:status', !props.status)
}

const switchMouseEnter = (e: MouseEvent) => {
    isChangePoint.value = true
}

const switchMouseDown = (e: MouseEvent) => {
    isChangePoint.value = true
}

const switchMouseLeave = (e: MouseEvent) => {
    isChangePoint.value = false
}

const switchMouseUp = (e: MouseEvent) => {
    isChangePoint.value = false
}

</script>

<style scoped lang="scss">
.y-switch {
    display: inline-block;
}

.y-switch-btn {
    overflow: hidden;
    box-sizing: border-box;
    min-width: calc(v-bind("props.width") * 1px);
    height: 25px;
    padding: 5px 5px;
    border-radius: 25px;

    background-color: rgb(210, 212, 212);
    cursor: pointer;

    display: flex;
    align-items: center;

    position: relative;

    transition: all 0.5s linear;
    .point {
        box-sizing: border-box;
        width: 15px;
        height: 15px;
        background-color: whitesmoke;
        border-radius: 100%;
        position: absolute;
        left: calc(0% + 5px);

        transition: all 0.5s linear;
        animation: pointAnima 1s linear infinite;

        z-index: 9;
    }

    .point-after {
        left: calc(100% - 20px);
        animation: pointAnima 1s linear infinite;
    }

    .point-change {
        width: 18px;
    }

    @keyframes pointAnima {
        0% {
            transform: scale(1);
        }

        50% {
            transform: scale(1.3);
        }

        100% {
            transform: scale(1);
        }
    }
}

.y-switch-btn-disable {
    cursor: not-allowed;
}

.y-switch-btn-active {
    background-color: rgb(43, 197, 159);

    transition: all 0.5s linear;
}

.text-wrapper {
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    font-size: 15px;
    font-weight: 400;
}

.text-wrapper-before {
    color: v-bind("props.trueLabelColor");
    margin: 0 25px 0 10px;
    animation: a_before 0.6s linear;
    @keyframes a_before {
        0% {
            transform: translateX(-100%);
        }
        100% {
        }
    }
}

.text-wrapper-after {
    color: v-bind("props.falseLabelColor");
    margin: 0 10px 0 25px;
    animation: a_after 0.6s linear;
    @keyframes a_after {
        0% {
            transform: translateX(100%);
        }

        100% {
        }
    }
}
</style>
